﻿using LuaInterface;
using LuaFramework;
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System;
using Assets.Script.Config;

public class BattleMgr : MonoBehaviourSingleton<BattleMgr>
{
    public delegate void AllTroopInitFinish();
    public event AllTroopInitFinish onAllTroopInitFinish;

    private bool _isLeft;

    private Dictionary<int, Troop> _troopDic = new Dictionary<int, Troop>();
    private Dictionary<string, GameObject> _unitPrefabDic = new Dictionary<string, GameObject>();
    private Dictionary<string, Material> _paperTroopMatDic = new Dictionary<string, Material>();
    private Dictionary<int, List<BattleFragment>> _battleFragmentDic = new Dictionary<int, List<BattleFragment>>();
    private Dictionary<string, List<ActionInfo>> _battleActionInfoDic = new Dictionary<string, List<ActionInfo>>();
    private Dictionary<string, ArmyInfo> _armyInfoDic = new Dictionary<string, ArmyInfo>();
    private Dictionary<int, GameObject> _effectPartGoDic = new Dictionary<int, GameObject>();
    private List<string> _takeABResNameList = new List<string>();
    private Dictionary<int, GameObject> _heroPrefabDic = new Dictionary<int, GameObject>();
    private Dictionary<string, Material> _unitRedBlueMat = new Dictionary<string, Material>();

    private const float _zOffset = 5;
    public Dictionary<int, Vector3> m_troopPos 
    {
        get {
            if (BattleSettings.s_bShowHero)
            {
                return _HaveHeroTroopPos;
            }
            else
            {
                return _NoHeroTroopPos;
            }
        }
    }
    private Dictionary<int, Vector3> _NoHeroTroopPos = new Dictionary<int, Vector3>()
    {
        {0,new Vector3(0,0,-18)},{1,new Vector3(0,0,-16)},{2,new Vector3(0,0,-14)},
        {3,new Vector3(0,0,7)},{4,new Vector3(0,0,13)},{5,new Vector3(0,0,19)}
    };
    private Dictionary<int, Vector3> _HaveHeroTroopPos = new Dictionary<int, Vector3>()
    {
         {0,new Vector3(3,0,-19)},{1,new Vector3(3,0,-19 + _zOffset*1)},{2,new Vector3(3,0,-19 + _zOffset * 2)},
        {3,new Vector3(3,0,19 -2 * _zOffset)},{4,new Vector3(3,0,19 - 1 * _zOffset)},{5,new Vector3(3,0,19)}
    };


    public void Clear()
    {
        for (int i = 0; i < 6; i++)
        {
            if (_troopDic.ContainsKey(i))
            {
                _troopDic[i].Clear();
            }
        }
        _troopDic.Clear();
        _unitPrefabDic.Clear();
        _battleFragmentDic.Clear();
        _battleActionInfoDic.Clear();
        _armyInfoDic.Clear();
        _effectPartGoDic.Clear();
        /*
        List<string> materialsNameList = new List<string>(_paperTroopMatDic.Keys);
        for (int i = 0; i < materialsNameList.Count; i++)
        {
            // Destroy(_paperTroopMatDic[materialsNameList[i]]);
        }
        */ 
        _paperTroopMatDic.Clear();
        _unitRedBlueMat.Clear();
    }

  

    private List<int> _needPreloadSkillEffIdList = new List<int>();
    private List<int> _needPreloadEffectPartIdList = new List<int>(); 

    private int _hasLoadNum;
    private int _needLoadNum;

    private int _nowRoundNum = 0;
    private int _nowRoundPlayFightNum = 0;
    private bool _waitDoFight = false;
    public bool _doFight = false;
    private float _timer;

    private bool _checkResourcesLoad = false;

    /// <summary>
    /// Old 初始化战报json转化为 BattleFragment逻辑片
    /// </summary>
    /// <param name="isLeft"></param>
    /// <param name="fightDetailInfo"></param>
    public void TranslateBattleInfo(bool isLeft, FightDetailInfo fightDetailInfo)
    {
        _nowRoundNum = -1;
        _isLeft = isLeft;
        TranslateForceInfo(fightDetailInfo.forceInfo);
        TranslateEveryCountFightRt(fightDetailInfo.everyCountFightRt);
        PreLoadAllEffectPart();
    }

    /// <summary>
    /// New 初始化战报json转化为 BattleFragment逻辑片
    /// </summary>
    /// <param name="isLeft"></param>
    /// <param name="fightInfoD"></param>
    public void TranslateBattleInfoNew(bool isLeft, FightInfoD fightInfoD)
    {
        _nowRoundNum = 0;
        _isLeft = isLeft;
        TranslateForceInfoNew(fightInfoD.forceInfo);
        TranslateEveryCountFightNew(fightInfoD.fightInfoD);
        PreLoadAllEffectPart();
    }

    void Update() 
    {
        if (_doFight) 
        {
            if (_waitDoFight)
            {
                RealPlayNextFragment();
            }
        }
    }

    void FixedUpdate()
    {
        if (!BattleStage.g_InBattle)
        {
          return;
        }
        if (_checkResourcesLoad == true)
        {
            CheckAllResLoadFin();
        }
        _timer += Time.deltaTime;
        if (_doFight)
        {
             _battleFragmentDic[_nowRoundNum][_nowRoundPlayFightNum].OnUpdate();
            CheckTime();
        }
    }

    /// <summary>
    /// 人物模型,材质球,特效  加载完毕, 开始实例化部队
    /// </summary>
    private void CheckAllResLoadFin()
    {
        if (_hasLoadNum < _needLoadNum)
        {
            return;
        }
        else
        {
            _checkResourcesLoad = false;
            UpdatePhyData();
            for (int i = 0; i < 6; i++)
            {
                if (_troopDic.ContainsKey(i))
                {
                    _troopDic[i].BuildUnits();
                    if (BattleSettings.s_bShowHero)
                    {
                        _troopDic[i].BuildHero();
                    }
                }
                if (onAllTroopInitFinish != null)
                {
                    //Debug.Log("已经初始化完毕");
                    onAllTroopInitFinish();
                }
            }
        }
    }

    public void UpdatePhyData()
    {
        List<string> useUnitTypeList = new List<string>(_armyInfoDic.Keys);
        for (int i = 0; i < useUnitTypeList.Count; i++)
        {
            ArmyInfo ai = _armyInfoDic[useUnitTypeList[i]];
            PhysicData pd = BattleSettings.Instance._physicDataDic[useUnitTypeList[i]];
            ai._radius = pd._radius;
            ai._atten = pd._atten;
            ai._strength = pd._strength;
            ai._pushStrength = pd._pushStrength;
            ai._colliTime = pd._colliTime;
            ai._pushTime = pd._pushTime;
        }
    }

    /// <summary>
    /// 加载 特效
    /// </summary>
    private void PreLoadAllEffectPart()
    {
        for (int i = 0; i < NeedPreloadBeList.Count; i++)
        {
            BattleEffect be = ConfigManager.Instance.BattleEffectLoader.GetInfoById(NeedPreloadBeList[i]);
            if (be != null)
            {
                for (int j = 0; j < be._battleEffectPartList.Count; j++)
                {
                    if (!_needPreloadEffectPartIdList.Contains(be._battleEffectPartList[j]))
                    {
                        _needPreloadEffectPartIdList.Add(be._battleEffectPartList[j]);
                    }
                }
            }
        }
        foreach (var battleActionInfoPair in _battleActionInfoDic)
        {
            for (int i = 0; i < battleActionInfoPair.Value.Count; i++)
            {
                BattleEffect be = ConfigManager.Instance.BattleEffectLoader.GetInfoById(battleActionInfoPair.Value[i]._effectId);
                if (be != null)
                {
                    for (int j = 0; j < be._battleEffectPartList.Count; j++)
                    {
                        if (!_needPreloadEffectPartIdList.Contains(be._battleEffectPartList[j]))
                        {
                            _needPreloadEffectPartIdList.Add(be._battleEffectPartList[j]);
                        }
                    }
                }
            }
        }
        for (int i = 0; i < _needPreloadEffectPartIdList.Count; i++)
        {
            BattleEffectPart bep = ConfigManager.Instance.BattleEffectPartLoader.GetInfoById(_needPreloadEffectPartIdList[i]);
            _needLoadNum += 1;
            _takeABResNameList.Add(bep._effectPartPath);
            AEResources.Load(bep._effectPartPath, typeof(GameObject),
                delegate(UnityEngine.Object obj)
                {
                    if (!_effectPartGoDic.ContainsKey(bep._effectPartId))
                    {
                        _effectPartGoDic.Add(bep._effectPartId, obj as GameObject);

                    }
                    _hasLoadNum += 1;
                });
        }
        _checkResourcesLoad = true;
    }


    public BattleFragment GetNowBattleFragment()
    {
        if (_battleFragmentDic.ContainsKey(_nowRoundNum) && _nowRoundPlayFightNum<_battleFragmentDic[_nowRoundNum].Count)
        {
            return _battleFragmentDic[_nowRoundNum][_nowRoundPlayFightNum];
        }
        else
        {
            return null;
        }
      
    }

    private void TranslateForceInfoNew(List<ReportForce> reportForceList)
    {
        for (int i = 0; i < reportForceList.Count; i++)
        {
            //Debug.LogFormat("isLeft {0}  address {1}", reportForceList[i].isLeft, reportForceList[i].address);
            Debug.LogWarning("Skills:    "+reportForceList[i].skills);

            GameObject troopGo = new GameObject();
            troopGo.transform.parent = this.transform;
            troopGo.AddComponent<Troop>();
            Troop t = troopGo.GetComponent<Troop>();
            int troopIndex = 0;
            if (reportForceList[i].isLeft == 0)
            {
                if (_isLeft)
                {
                    troopIndex = reportForceList[i].address - 1;
                }
                else
                {
                    troopIndex = 6 - reportForceList[i].address;
                }
            }
            else
            {
                if (_isLeft)
                {
                    troopIndex = 6 - reportForceList[i].address;
                }
                else
                {
                    troopIndex = reportForceList[i].address - 1;
                }
            }
            ArmyInfo ai = ConfigManager.Instance.ArmyLoader.GetInfoById(reportForceList[i].changeBinzhong);
            string unitType = ai._prefabName;
            //int unitTotalNum = Mathf.Min(Mathf.CeilToInt((float)reportForceList[i].bingliBeforeFight / (float)ai._changeRate), ai._maxTotalNum);
            int unitTotalNum = Mathf.Min(Mathf.CeilToInt((float)reportForceList[i].bingliBeforeFight / (float)ai._changeRate), 10);
            if (BattleSettings.s_bTestTroopNum)
            {
                unitTotalNum = BattleSettings.s_troopNum;
                unitType = BattleSettings._batman;
            }

            bool onlyOnePart = false;
            t.Init(troopIndex, unitType, onlyOnePart, unitTotalNum, reportForceList[i].heroId, reportForceList[i].protoId, reportForceList[i].allHp,reportForceList[i].skills,reportForceList[i].address);
            troopGo.name = "HeroId:" + reportForceList[i].heroId + "  Left:" + reportForceList[i].isLeft + "  Address:" + reportForceList[i].address + "  TroopIndex: " + troopIndex;
            _troopDic.Add(troopIndex, t);
            if (!UnitPrefabDic.ContainsKey(unitType))
            {

                _unitPrefabDic.Add(unitType, null);
                ArmyInfoDic.Add(unitType, ai);
                _needLoadNum += 1;
                StringBuilder sb = new StringBuilder();
                sb.Append("Battle/Troop/");
                sb.Append(unitType);
                sb.Append("/Prefab/");
                sb.Append(unitType);
                if (ai._paperModel == 1)
                {
                    LoadUnitNeedMaterials(unitType);
                }
                else
                {
                    sb.Append("_3D");
                }
                _takeABResNameList.Add(sb.ToString());
                AEResources.Load(sb.ToString(), typeof(GameObject),
                delegate(UnityEngine.Object obj)
                {
                    _unitPrefabDic[unitType] = obj as GameObject;
                    //GameObject go = GameObject.Instantiate(_unitPrefabDic[unitType]);
                    _hasLoadNum += 1;
                });
                // todo ,读取所有动作的;
                List<ActionInfo> actionInfoList = new List<ActionInfo>();
                for (int j = 0; j < ai._attackInfoDic.Count; j++)
                {
                    ActionInfo actionInfo = ConfigManager.Instance.ActionLoader.GetInfoById(ai._attackInfoDic[j]);
                    actionInfoList.Add(actionInfo);
                }
                BattleActionInfoDic.Add(unitType, actionInfoList);
                //Debug.Log(unitType + actionInfoList[0]._lastTime);

                //加载不同颜色材质球
                LoadUnitRedBlueMaterials(unitType);
            }
            //加载英雄模型
            int hero = GetHeroPath(reportForceList[i].protoId);
            string heroResPath = BattleSettings.s_bTestTroopNum ? "Battle/Hero/hero1":BattleSettings.sHeroResPath[hero];
            if (!_heroPrefabDic.ContainsKey(hero))
            {
                _needLoadNum++;
                AEResources.Load(heroResPath, typeof(GameObject), delegate(UnityEngine.Object obj)
                  {
                      _heroPrefabDic[hero] = (GameObject)obj;
                      _hasLoadNum++;
                  });
            }
        }
    }

    private void TranslateForceInfo(List<ForceInfoRt> forceInfoList)
    {
        for (int i = 0; i < forceInfoList.Count; i++)
        {
            GameObject troopGo = new GameObject();
            troopGo.transform.parent = this.transform;
            troopGo.AddComponent<Troop>();
            Troop t = troopGo.GetComponent<Troop>();
            int troopIndex = 0;
            if (forceInfoList[i].isLeft == 0)
            {
                if (_isLeft)
                {
                    troopIndex = forceInfoList[i].address - 1;
                }
                else
                {
                    troopIndex = 6 - forceInfoList[i].address;
                }
            }
            else
            {
                if (_isLeft)
                {
                    troopIndex = 6 - forceInfoList[i].address;
                }
                else
                {
                    troopIndex = forceInfoList[i].address - 1;
                }
            }
            ArmyInfo ai = ConfigManager.Instance.ArmyLoader.GetInfoById(forceInfoList[i].changeBinzhong);
            string unitType = ai._prefabName;
            int unitTotalNum = Mathf.Min(Mathf.CeilToInt((float)forceInfoList[i].bingliBeforeFight / (float)ai._changeRate), ai._maxTotalNum);
            bool onlyOnePart = false;
            t.Init(troopIndex, unitType, onlyOnePart, unitTotalNum, forceInfoList[i].heroId, forceInfoList[i].protoId, forceInfoList[i].bingliBeforeFight, forceInfoList[i].skills,forceInfoList[i].address);
            troopGo.name = "Troop_" + troopIndex;
            _troopDic.Add(troopIndex, t);
            if(!UnitPrefabDic.ContainsKey(unitType))
            {
                _unitPrefabDic.Add(unitType, null);
                ArmyInfoDic.Add(unitType, ai);
                _needLoadNum += 1;
                StringBuilder sb = new StringBuilder();
                sb.Append("Battle/Troop/");
                sb.Append(unitType);
                sb.Append("/Prefab/");
                sb.Append(unitType);
                if (ai._paperModel == 1)
                {
                    LoadUnitNeedMaterials(unitType);
                }
                else 
                {
                    sb.Append("_3D");
                }
                _takeABResNameList.Add(sb.ToString());
                AEResources.Load(sb.ToString(), typeof(GameObject),
                delegate (UnityEngine.Object obj)
                {
                    _unitPrefabDic[unitType] = obj as GameObject;
                    //GameObject go = GameObject.Instantiate(_unitPrefabDic[unitType]);
                    _hasLoadNum += 1;
                });
                // todo ,读取所有动作的;
                List<ActionInfo> actionInfoList = new List<ActionInfo>();
                for(int j =0;j< ai._attackInfoDic.Count; j++)
                {
                    ActionInfo actionInfo = ConfigManager.Instance.ActionLoader.GetInfoById(ai._attackInfoDic[j]);
                    actionInfoList.Add(actionInfo);
                }
                BattleActionInfoDic.Add(unitType, actionInfoList);
                //Debug.Log(unitType + actionInfoList[0]._lastTime);
            }
        }
    }

    private void LoadUnitNeedMaterials(string unitType)
    {
        for (int i = 0; i < BattleSettings.Instance._paperModelUnitBaseActionList.Count; i++)
        {
            for (int j = 0; j < 8; j++)
            {
                int angleNum = j * 45;
                string materialName = unitType + "_" + BattleSettings.Instance._paperModelUnitBaseActionList[i] + "_" + angleNum;
                if (!_paperTroopMatDic.ContainsKey(materialName))
                {
                    _needLoadNum += 1;
                    _takeABResNameList.Add("Battle/Troop/" + unitType + "/Material/" + materialName);
                    AEResources.Load("Battle/Troop/" + unitType + "/Material/" + materialName, typeof(Material), delegate (UnityEngine.Object obj)
                    {
                        _paperTroopMatDic[materialName] = obj as Material;
                        _hasLoadNum += 1;
                    });
                }
            }
        }
    }

    private void LoadUnitRedBlueMaterials(string unitType)
    {
        string matPath = "Battle/Troop/" + unitType + "/Model/Materials/";
        _needLoadNum += 1;
        _takeABResNameList.Add(matPath + unitType + BattleSettings.MatRed);
        AEResources.Load(matPath + unitType + BattleSettings.MatRed, typeof(Material), delegate(UnityEngine.Object obj)
        {
            _unitRedBlueMat[unitType + BattleSettings.MatRed] = obj as Material;
            _hasLoadNum += 1;
        });

        _needLoadNum += 1;
        _takeABResNameList.Add(matPath + unitType + BattleSettings.MatBlue);
        AEResources.Load(matPath + unitType + BattleSettings.MatBlue, typeof(Material), delegate(UnityEngine.Object obj)
        {
            _unitRedBlueMat[unitType + BattleSettings.MatBlue] = obj as Material;
            _hasLoadNum += 1;
        });
    }

    private int _currentDealRoundNum;
    private int _currentDealPartNum;
    private BattleFragment _currentFragment;



    private void TranslateEveryCountFightNew(List<oneFightInfoD> oneFightInfoList)
    {
        for (int i = 0; i < oneFightInfoList.Count; i++)
        {
            oneFightInfoD ofi = oneFightInfoList[i];

            //Debug.LogFormat("解析： {0}  {1}  {2} ", _currentDealRoundNum, _currentDealPartNum,ofi.action);
            switch (ofi.action)
            {
                case 1:
                    break;
                case 2:
                    break;
                case 3:
                    break;
                case 4:
                    break;
                case 5:
                    break;
                case 6:
                    break;
                case 7:
                    break;
                case 8:
                    break;
                case 9:
                    break;
                case 10:
                    break;
                case 11:
                    break;
                case 12:
                    break;
                case 13:
                    break;
                case 14:
                    break;
                case 15:
                    break;
                case 16:
                    break;
                case 17:
                    // 准备回合开始
                    _currentDealRoundNum = 0;
                    _currentDealPartNum = -1;
                    List<BattleFragment> getReadyRoundFragmentList = new List<BattleFragment>();
                    _battleFragmentDic.Add(_currentDealRoundNum, getReadyRoundFragmentList);
                    break;
                case 18:
                    // [afaeac]第$1回合[-]
                    // 第X回合
                    _currentDealRoundNum = (int)ofi.values[0];
                    _currentDealPartNum = -1;
                    List<BattleFragment> oneRoundFragmentList = new List<BattleFragment>();
                    _battleFragmentDic.Add(_currentDealRoundNum, oneRoundFragmentList);
                    break;
                case 19:
                    // [afaeac]战斗结束[-]
                    // 不处理
                    break;
                case 20:
                    // [ffffff]$1发动【$2】！[-]
                    // 发动技能
                    _battleFragmentDic[_currentDealRoundNum][_currentDealPartNum].AddSkillResult((int)ofi.values[1]);
                    break;
                case 21:
                    // $1对$2发动普通攻击[-]
                    //Debug.LogFormat( "添加攻擊結構體： {0}  {1} ", _currentDealRoundNum, _currentDealPartNum);
                    _battleFragmentDic[_currentDealRoundNum][_currentDealPartNum].AddNormalAttack(ofi.values[0], ofi.values[1]);
                    break;
                case 22:
                    // [ffffff]$1损失了[f1c74a]$2[-]兵力($3) [-]($4) 
                    //Debug.LogFormat("添加攻擊數值__普工型號  {0}  {1} ", _currentDealRoundNum, _currentDealPartNum);
                    _battleFragmentDic[_currentDealRoundNum][_currentDealPartNum].MakeDamage(ofi.values[0], (int)ofi.values[1], (int)ofi.values[2], (int)ofi.values[3],false);
                    break;
                case 23:
                    // [ffffff]$1回复了[f1c74a]$2[-]兵力($3) [-]($4)
                    _battleFragmentDic[_currentDealRoundNum][_currentDealPartNum].MakeTreatment(ofi.values[0], (int)ofi.values[1], (int)ofi.values[2], (int)ofi.values[3]);
                    break;
                case 24:
                    // [ffffff]$1的$2了[f1c74a]$3[-] ($4) [-]
                    // skilleff属性转换
                    _battleFragmentDic[_currentDealRoundNum][_currentDealPartNum].AddSkillPart(ofi.values[0],(int)ofi.values[1], (int)ofi.values[2], (int)ofi.values[3],false);
                    break;
                case 25:
                    break;
                case 26:
                    // 与24号协议几乎相同，忽略
                    break;
                case 27:
                    break;
                case 28:
                    break;
                case 29:
                    break;
                case 30:
                    // [ffffff]$1准备凭借攻击进行吸血([f1c74a]$2[-]%) [-]
                    // 忽略
                    break;
                case 31:
                    // [ffffff]$1由于吸血回复了[f1c74a]$2[-]兵力($3) [-]
                    _battleFragmentDic[_currentDealRoundNum][_currentDealPartNum].MakeVampire((int)ofi.values[1]);
                    break;
                case 32:
                    break;
                case 33:
                    // [ffffff]$1的来自$2【$3】的($4)效果消失了[-]
                    _battleFragmentDic[_currentDealRoundNum][_currentDealPartNum].AddBeforeDoAction(ofi.values[0], ofi.values[1], (int)ofi.values[2], (int)ofi.values[3], 0, BeforeDoActionState.BuffOff);
                    break;
                case 34:
                    break;
                case 35:
                    break;
                case 36:
                    break;
                case 37:
                    break;
                case 38:
                    break;
                case 39:
                    break;
                case 40:
                    break;
                case 41:
                    // [ffffff]$1【$2】令$3陷入眩晕中[-]
                    // 目标进入眩晕状态
                    break;
                case 42:
                    // [ffffff]$1无法行动[-]
                    // 不处理
                    break;
                case 43:
                    break;
                case 44:
                    // [ffffff]$1由于$2【$3】施加的$4效果损失了[f1c74a]$5[-]兵力($6) [-]
                    _battleFragmentDic[_currentDealRoundNum][_currentDealPartNum].AddBeforeDoAction(ofi.values[0], ofi.values[1], (int)ofi.values[2], (int)ofi.values[3], (int)ofi.values[4], BeforeDoActionState.Damage);
                    break;
                case 45:
                    // [ffffff]$1【$2】的休整效果为$3回复了[f1c74a]$4[-]兵力($5) [-]
                    _battleFragmentDic[_currentDealRoundNum][_currentDealPartNum].AddBeforeDoAction(ofi.values[2], 0, (int)ofi.values[0], (int)ofi.values[1], (int)ofi.values[3], BeforeDoActionState.Treatment);
                    break;
                case 46:
                    break;
                case 47:
                    break;
                case 48:
                    // [ffffff]$1已存在$2效果[-]
                    // 不处理
                    break;
                case 49:
                    break;
                case 50:
                    break;
                case 51:
                    //$1的技能$2开始准备！
                    _battleFragmentDic[_currentDealRoundNum][_currentDealPartNum].AddSkillResult((int)ofi.values[1],true);
                    break;
                case 52:
                    break;
                case 53:
                    // [ffffff]$1执行溅射[-]
                    _battleFragmentDic[_currentDealRoundNum][_currentDealPartNum].ChangeNextNormalAttackState(NormalAttackState.Sputtering);
                    break;
                case 54:
                    break;
                case 55:
                    break;
                case 56:
                    break;
                case 57:
                    break;
                case 58:
                    break;
                case 59:
                    // miss
                    break;
                case 60:
                    // [ffffff]$1由于处于庇护状态，伤害无效[-]
                    //Debug.LogFormat("庇護狀態  {0}  {1} ", _currentDealRoundNum, _currentDealPartNum);
                    _battleFragmentDic[_currentDealRoundNum][_currentDealPartNum].MakeDamage(ofi.values[0], 0, 0,(int)ofi.values[1],false);
                    break;
                case 61:
                    break;
                case 62:
                    break;
                case 63:
                    break;
                case 64:
                    break;
                case 65:
                    break;
                case 66:
                    break;
                case 67:
                    break;
                case 68:
                    break;
                case 69:
                    break;
                case 70:
                    // [ffffff]$1获得反击能力[-]
                    // 不处理
                    break;
                case 71:
                    // [ffffff]$1进行反击[-]
                    _battleFragmentDic[_currentDealRoundNum][_currentDealPartNum].ChangeNextNormalAttackState(NormalAttackState.FightBack);
                    break;
                case 72:
                    // [ffffff]$1$2$3%[-]
                    // 处理方法未定！GG  todo
                    // 由于本身存在的buff对技能造成的加成
                    break;
                case 73:
                    break;
                case 74:
                    break;
                case 75:
                    break;
                case 76:
                    break;
                case 77:
                    break;
                case 78:
                    break;
                case 79:
                    break;
                case 80:
                    break;
                case 81:
                    break;
                case 82:
                    break;
                case 83:
                    break;
                case 84:
                    //-该次攻击造成了暴击，{$1:hero}损失了-(font color='#f1c74a')-{$2:value}-(/font)-兵力({$3:value}) -(/font)-"/>
                    _battleFragmentDic[_currentDealRoundNum][_currentDealPartNum].MakeDamage(ofi.values[0], (int)ofi.values[1], (int)ofi.values[2], (int)ofi.values[3], true);
                    break;

                case 1000:
                    // [$1]部队开始行动
                    _currentDealPartNum += 1;
                    BattleFragment newBattleFragment = new BattleFragment();
                    newBattleFragment.SetDoActionHeroID(ofi.values[0]);
                    _battleFragmentDic[_currentDealRoundNum].Add(newBattleFragment);
                    break;
            }
        }
    }

    private void TranslateEveryCountFightRt(List<EveryCountFightRt> everyCountFightRtList)
    {
        for (int i = 0; i < everyCountFightRtList.Count; i++)
        {
            List<BattleFragment> battleFragmentList = new List<BattleFragment>();
            for (int j = 0; j < everyCountFightRtList[i].everyOneFightRt.Count; j++)
            {
                BattleFragment bf = new BattleFragment();
                // bf.TranslateEveryOneFightRt(everyCountFightRtList[i].everyOneFightRt[j]);
                battleFragmentList.Add(bf);
            }
            _battleFragmentDic.Add(everyCountFightRtList[i].countNum, battleFragmentList);
        }
    }

    public void IntoFightWatch()
    {
        BattleCameraCtrl.Instance.IntoBattleEffect();
    }

    public void PlayFragment()
    {
         //Debug.Log("Start Fight");
         //Debug.Log(_nowRoundNum);
        if (_battleFragmentDic.ContainsKey(_nowRoundNum))
        {
            if (_nowRoundPlayFightNum < _battleFragmentDic[_nowRoundNum].Count)
            {
                OnRoundNumChange(_nowRoundNum);
                _doFight = true;
               _battleFragmentDic[_nowRoundNum][_nowRoundPlayFightNum].OnStart();
            }
            else
            {
                if (_nowRoundNum == -1)
                {
                    _nowRoundPlayFightNum = 0;
                    _nowRoundNum = 1;
                    PlayFragment();
                }
                else
                {
                    BattleFightEnd();
                }

            }
        }
        else
        {
            BattleFightEnd();
        }
    }

    public void PlayNextFragment()
    {
        _waitDoFight = true;
    }
    private void RealPlayNextFragment() 
    {
        _waitDoFight = false;
        _nowRoundPlayFightNum += 1;
        if (_nowRoundPlayFightNum < _battleFragmentDic[_nowRoundNum].Count)
        {
            _doFight = true;
            _battleFragmentDic[_nowRoundNum][_nowRoundPlayFightNum].OnStart();
        }
        else
        {
            _nowRoundPlayFightNum = 0;
            if (_nowRoundNum == -1)
            {
                _nowRoundNum += 2;
            }
            else
            {
                _nowRoundNum += 1;
            }
            PlayFragment();
        }
    }


    private void BattleFightEnd()
    {
        Invoke("BattleGG", 3);
        _doFight = false;
    }

    public void StopFight() 
    {
        _doFight = false;
    }

    public int GetTroopIndexByHeroId(long heroId)
    {
        for (int i = 0; i < 6; i++)
        {
            if (_troopDic.ContainsKey(i))
            {
                if (_troopDic[i].HeroId == heroId)
                {
                    return i;
                }
            }
        }

        //for (int i = 0; i < 6; i++)
        //{
        //    if (_troopDic.ContainsKey(i))
        //    {
        //        Debug.Log(_troopDic[i].HeroId);
        //    }
        //}
        //Debug.Log("没有找到这个heroId: " + heroId.ToString());

        return -1;
    }

    public static float GetAngle(Vector3 vec3Dir)
    {
        Vector3 lookDir = vec3Dir.normalized;
        float angle = Mathf.Acos(Vector3.Dot(lookDir, Vector3.forward)) * Mathf.Rad2Deg;
        if (Vector3.Dot((Vector3.Cross(lookDir, Vector3.forward)), Vector3.up) > 0)
        {
            angle = 360 - angle;
        }
        return angle;
    }

    public static int GetHeroPath(int heroPid)
    {
        int index = 0;
        LuaTable luaT = (LuaTable)DKLuaMgr.Instance.InvokeFunction<LuaTable>("CsharpLuaInterface.GetUnitBase", heroPid);
        // LuaTable luaT = (LuaTable)objs[0];
        //index = Convert.ToInt32(luaT["sex"]) * Convert.ToInt32(luaT["army"]);
        index =  Convert.ToInt32(luaT["army"]);
        return index;
    }

    public static bool IsSameSide(int tagIndex, int myIndex) 
    {
        if (tagIndex >= 3)
        {
            if (myIndex >= 3)
                return true;
            else
                return false;
        }
        else 
        {
            if (myIndex < 3)
                return true;
            else
                return false;
        }
    }

    #region 对外事件
    public void OnChangeBattleCameraFixedState()
    {
        BattleCameraCtrl.Instance.OnChangeBattleCameraState();
    }

    public void OnStartBattle() 
    {
        DKLuaMgr.Instance.CallFunction("LuaUpdater.StartBattle");
        // LuaFramework.Util.CallMethod("LuaUpdater", "StartBattle");
    }

    public void OnRoundNumChange(int roundNum)
    {
        if (_doFight)
        {
            // 回合数变化
            DKLuaMgr.Instance.CallFunction("LuaUpdater.RoundChange");
            // LuaFramework.Util.CallMethod("LuaUpdater", "RoundChange", roundNum);
        }
    }

    public void ChangeTimeScale(float timeScale)
    {
         Time.timeScale = timeScale;
        // 时间片变化
    }

    public void TroopHpChange(int doActionTroopIndex, int troopIndex, int changeNum,bool needAutoDead,bool isCri,bool isShowHud)
    {
        if (_doFight)
        {
            _troopDic[troopIndex].TroopHpChange(changeNum, needAutoDead);
            // 所有加血扣血都会通过这里
            DKLuaMgr.Instance.CallFunction("LuaUpdater.HpChange", doActionTroopIndex, troopIndex, changeNum, isCri, isShowHud);
            // LuaFramework.Util.CallMethod("LuaUpdater", "HpChange", doActionTroopIndex, troopIndex, changeNum, isCri, isShowHud);
        }
    }

    public void TroopStartAction(int troopIndex)
    {
        if (_doFight)
        {
            //Debug.Log(troopIndex);
            // 哪个部队开始行动
            DKLuaMgr.Instance.CallFunction("LuaUpdater.TroopStartAction", troopIndex);
        }
    }

    //显示buf结算时候的扣血文字
    public void DoBufEff(int index,int skillId,int skillEffId,int value,bool isAdd)
    {
        if (_doFight)
        {
            //Debug.LogFormat("{0}  {1}  {2}  {3}", index, skillId, skillEffId, value);
            DKLuaMgr.Instance.CallFunction("LuaUpdater.PlayBufEff", index, skillId, skillEffId, value, isAdd);
        }
    }

    //显示buf结算时候的通用特效
    public void ShowBufEffect(bool isAdd, GameObject go, Vector3 pos)
    {
        if (_doFight)
        {
            DKLuaMgr.Instance.CallFunction("LuaUpdater.PlayBufEffect", isAdd, go, pos);
        }
    }



    //播放特寫技能
    public void PlayFeature(int index,int skillId)
    {
        if (_doFight)
        {
            //Debug.LogFormat("PlayFeature : {0}", skillId);
            // 使用技能
            DKLuaMgr.Instance.CallFunction("LuaUpdater.PlayFeature", index, skillId);
        }
    }

    //播放非特寫技能
    public void PlaySkillName(int index, int skillId)
    {
        if (_doFight)
        {
            DKLuaMgr.Instance.CallFunction("LuaUpdater.PlaySkillName", index, skillId);
        }
    }

    //播放追击技能名字
    public void PlayAddSkillName(int index, int skillId)
    {
        if (_doFight)
        {
            DKLuaMgr.Instance.CallFunction("LuaUpdater.PlayAddSkillName", index, skillId);
        }
    }
    //播放攻击二个字
    public void PlayAttackName(int index)
    {
        if (_doFight)
        {
            DKLuaMgr.Instance.CallFunction("LuaUpdater.PlayAttack", index);
        }
    }

    //播放吟唱技能
    public void PlaySingSkillName(int index, int skillId)
    {
        if (_doFight)
        {
            DKLuaMgr.Instance.CallFunction("LuaUpdater.PlaySingSkillName", index, skillId);
        }
    }

    public void TroopBuffGet(int doSkillTroopId, int targetTroopId, int skillId, int skillEffId, int changeValue)
    {
        if (_doFight)
        {
            //Debug.LogFormat("TroopBuffGet : {0}",skillEffId);
            // 使用技能
            DKLuaMgr.Instance.CallFunction("LuaUpdater.AddBuf", doSkillTroopId, targetTroopId, skillId, skillEffId, changeValue);
        }
    }

    public void TroopBuffOff(int troopIndex, int effectId, int effecteffId)
    {
        if (_doFight)
        {
            ////Debug.Log("过期吧.....");
            DKLuaMgr.Instance.CallFunction("LuaUpdater.DelBuf", troopIndex, effectId, effecteffId);
        }
    }

    //逻辑触发 显示技能选择UI
    public void TriggerSkill(int troopIndex,int skillId, List<BattleSkillResult> skills = null)
    {
        if (_doFight)
        {
            Debug.LogFormat("Troop: {0}  do Skill {1}", troopIndex, skillId);
            if (skills == null)
            {
                DKLuaMgr.Instance.CallFunction("LuaUpdater.PlaySkillTrigger", troopIndex, skillId, 0, 0, 0);
            }
            else
            {
                int[] s = new int[] { 0, 0, 0 };
                int len = skills.Count;
                if (len > 3)
                    len = 3;
                for (int i = 0; i < len; i++)
                {
                    s[GetSkillIndex(troopIndex, skills[i]._skillID)] = skills[i]._skillID;
                }
                DKLuaMgr.Instance.CallFunction("LuaUpdater.PlaySkillTrigger", troopIndex, skillId, s[0], s[1], s[2]);
            }
        }
    }

    //帮助方法
    private int GetSkillIndex(int troopIndex,int skillId) 
    {
        int [] s = _troopDic[troopIndex].Skills;
        for (int i = 0; i < s.Length; i++)
        {
            if (s[i] == skillId)
            {
                return i;
            }
        }
        return 0;
    }

    public void StartSingSkill(int troopIndex,int skillId)
    {
        DKLuaMgr.Instance.CallFunction("LuaUpdater.SingSkill", troopIndex, skillId);
    }

    //UI触发 技能选择结束
    public void TriggerSkillFinish()
    {
        if (_doFight)
        {
            _battleFragmentDic[_nowRoundNum][_nowRoundPlayFightNum].UITriggerEnd();
        }
    }

    public void PlayBuidlUpEff(int troopIndex, int skillId)
    {
        if (_doFight)
        {
            foreach (Troop troop in _troopDic.Values)
            {
                if (IsSameSide(troopIndex, troop.TroopIndex))
                {
                    DKLuaMgr.Instance.CallFunction("LuaUpdater", "PlayBuidlUpEff", troop.TroopIndex, skillId, _troopDic[troop.TroopIndex].GetTroopCenter(), this.gameObject);
                }
            }
        }
    }

    //部队死亡特效
    public void PlayTroopDead(int index)
    {
        if (_doFight)
        {
            DKLuaMgr.Instance.CallFunction("LuaUpdater", "PlayTroopDead", index);
        }
    }

    public void BattleGG()
    {
        Debug.Log("C# BattleGG");
        DKLuaMgr.Instance.CallFunction("LuaUpdater", "BattleOver");
    }
    #endregion

    #region 属性

    public List<string> TakeABResNameList
    {
        get { return _takeABResNameList; }
        set { _takeABResNameList = value; }
    }

    public Dictionary<string, Material> PaperTroopMatDic
    {
        get { return _paperTroopMatDic; }
        set { _paperTroopMatDic = value; }
    }
    public Dictionary<string, GameObject> UnitPrefabDic
    {
        get { return _unitPrefabDic; }
        set { _unitPrefabDic = value; }
    }
    public Dictionary<int, Troop> TroopDic
    {
        get { return _troopDic; }
        set { _troopDic = value; }
    }

    public Dictionary<string, List<ActionInfo>> BattleActionInfoDic
    {
        get
        {
            return _battleActionInfoDic;
        }

        set
        {
            _battleActionInfoDic = value;
        }
    }

    public Dictionary<string, ArmyInfo> ArmyInfoDic
    {
        get
        {
            return _armyInfoDic;
        }

        set
        {
            _armyInfoDic = value;
        }
    }

    public Dictionary<int, GameObject> EffectPartGoDic
    {
        get
        {
            return _effectPartGoDic;
        }

        set
        {
            _effectPartGoDic = value;
        }
    }

    public List<int> NeedPreloadBeList
    {
        get
        {
            return _needPreloadSkillEffIdList;
        }

        set
        {
            _needPreloadSkillEffIdList = value;
        }
    }

    public float Timer
    {
        get
        {
            return _timer;
        }

        set
        {
            _timer = value;
        }
    }

    public Dictionary<int, GameObject> HeroPreDic
    {
        get
        {
            return _heroPrefabDic;
        }
        set
        {
            _heroPrefabDic = value;
        }
    }

    public Material GetUnitMat(string unitType, bool isLeft)
    {
        string key = unitType + (isLeft? BattleSettings.MatBlue : BattleSettings.MatRed);
        if (_unitRedBlueMat.ContainsKey(key))
        {
            return _unitRedBlueMat[key];
        }
        return null;
    }

    public Vector3 GetHeroPos(Troop troop) 
    {
        float troopNum = 0;

        Vector3 off = troop.IsLeft ? new Vector3(0, 0, 3) : new Vector3(0, 0, -3);

        int centerIndex = 0;
        foreach (Troop t in _troopDic.Values)
        {
            if (troop.IsLeft == t.IsLeft)
            {
                if (t.Address > centerIndex)
                {
                    centerIndex = t.Address;
                }
                troopNum=troopNum + 1.0f;
            }
        }
        centerIndex = troop.IsLeft ? (centerIndex - 1) : (6 - centerIndex);
        off = off + m_troopPos[centerIndex];

        float mid = troopNum / 2;

        return off;
    }

    #endregion

    #region 计时器 战斗中的所有计时相关的都搬到这里, 暂时只搬了英雄里的
    public delegate void TimeInterval();
    private Dictionary<TimeInterval, float> _timeIntervalDic = new Dictionary<TimeInterval, float>();
    private List<TimeInterval> _timeKeys;
    public void AddInterval(TimeInterval interval,float t)
    {
        if(interval != null)
        {
            _timeIntervalDic[interval] = BattleMgr.Instance.Timer + t;
        }
    }

    public void RemoveInterval(TimeInterval interval)
    {
        if (interval != null)
        {
            if (_timeIntervalDic.ContainsKey(interval))
            {
                _timeIntervalDic.Remove(interval);
            }
        }
    }

    private void CheckTime()
    {
        if (_timeIntervalDic.Count > 0)
        {
            _timeKeys = new List<TimeInterval>(_timeIntervalDic.Keys);
            for(int i = 0; i < _timeKeys.Count; i++)
            {
                if (_timeIntervalDic[_timeKeys[i]] <= _timer)
                {
                    _timeKeys[i]();
                    RemoveInterval(_timeKeys[i]);
                }
            }
        }
    }
    #endregion
}
